package com.sduept.nwld.dataserver.manager.gismap;

import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class MapGisUtil {	
	public static final String SUPERMAP_GEOLINE_HEADER = "0000000001000000";
	
	public static final String bytesToHexString(byte[] bArray) {
		  StringBuffer sb = new StringBuffer(bArray.length);
		  String sTemp;
		  for (int i = 0; i < bArray.length; i++) {
		   sTemp = Integer.toHexString(0xFF & bArray[i]);
		   if (sTemp.length() < 2)
		    sb.append(0);
		   sb.append(sTemp.toUpperCase());
		  }
		  return sb.toString();
		 }
	public static final long swap64(long x){
		ByteBuffer buffer= ByteBuffer.allocate(8);
		buffer.order(ByteOrder.LITTLE_ENDIAN);
        buffer.putLong(x);
        buffer.order(ByteOrder.BIG_ENDIAN);
        buffer.position(0);
        long y = buffer.getLong();
        return y;
	}
	public static final String getBigEndianHexString(long value){
		ByteBuffer buffer= ByteBuffer.allocate(8);
		buffer.order(ByteOrder.LITTLE_ENDIAN);
		buffer.putLong(value);
		buffer.order(ByteOrder.BIG_ENDIAN);
		buffer.position(0);
		byte[] b = buffer.array();
		return bytesToHexString(b);
	}
	public static final byte[] getBigEndianBytes(List<double[]> values){
		ByteBuffer buffer= ByteBuffer.allocate(8*values.size()*2);
		buffer.order(ByteOrder.LITTLE_ENDIAN);
		for(double[] d : values){
			long vx = Double.doubleToLongBits(d[0]);
			buffer.putLong(vx);
			long vy = Double.doubleToLongBits(d[1]);
			buffer.putLong(vy);
		}
		buffer.order(ByteOrder.BIG_ENDIAN);
		buffer.position(0);
		byte[] b = buffer.array();
		return b;
	}
	/**
	 * 获取supermap line 对象的Geometry属性，该属性存到数据库中是LongBlob类型，
	 * 内容是16进制的经纬度集合的byte数组，字节是高位在前，java需转换
	 * 前面固定3个int型的头，0,1,经纬度长度
	 * @param values 经纬度集合，values[0] 为lon ，values[1] 为lat 
	 * @return
	 */
	public static final MapGisUtil.GeoLine getSuperMapLineGeoLine(List<double[]> values){
		MapGisUtil.GeoLine rtn = null;
		if(!values.isEmpty()){
			rtn = new MapGisUtil.GeoLine();
			//固定头
			//00000000
			//01000000
			//长度
			int len = values.size();
			ByteBuffer buffer= ByteBuffer.allocate(12+8*len*2);
			buffer.order(ByteOrder.LITTLE_ENDIAN);
			buffer.putInt(0);
			buffer.putInt(1);
			buffer.putInt(len);
			double[] firstP = values.get(0);
			rtn.smSdriW = rtn.smSdriE = firstP[0];
			rtn.smSdriS =  rtn.smSdriN = firstP[1];
			for(double[] ds : values){
				long vx = Double.doubleToLongBits(ds[0]);
				buffer.putLong(vx);
				long vy = Double.doubleToLongBits(ds[1]);
				buffer.putLong(vy);
				if(ds[0] < rtn.smSdriW){
					rtn.smSdriW = ds[0];
				} 
				if(ds[0] > rtn.smSdriE){
					rtn.smSdriE = ds[0];
				}
				if(ds[1] < rtn.smSdriS){
					rtn.smSdriS = ds[1];
				} 
				if(ds[1] > rtn.smSdriN){
					rtn.smSdriN = ds[1];
				}
			}
			buffer.order(ByteOrder.BIG_ENDIAN);
			buffer.position(0);
			rtn.smGeometry = buffer.array();
		}
		return rtn;
	}
	public static final String getBigEndianHexString(short value){
		ByteBuffer buffer= ByteBuffer.allocate(2);
		buffer.order(ByteOrder.LITTLE_ENDIAN);
		buffer.putShort(value);
		buffer.order(ByteOrder.BIG_ENDIAN);
		buffer.position(0);
		byte[] b = buffer.array();
		return bytesToHexString(b);
	}
	public static final String getBigEndianHexString(int value){
		ByteBuffer buffer= ByteBuffer.allocate(4);
		buffer.order(ByteOrder.LITTLE_ENDIAN);
		buffer.putInt(value);
		buffer.order(ByteOrder.BIG_ENDIAN);
		buffer.position(0);
		byte[] b = buffer.array();
		return bytesToHexString(b);
	}
	public static final  String getBigEndianHexString(double value){
		long value_64 = Double.doubleToLongBits(value);
		return getBigEndianHexString(value_64);
	}
	/**
	 * @param points List数组集合，对象double[0]为lon,double[1] 为lat
	 * @return
	 */
	public static final String getSuperMapLineGeoLineStr(List<double[]> points){
		String rtn = null;
		StringBuffer sb = new StringBuffer(SUPERMAP_GEOLINE_HEADER);
		if(!points.isEmpty()){
			String len = getBigEndianHexString(points.size());
			sb.append(len);
			for(double[] ds : points){
				sb.append(getBigEndianHexString(ds[0]));
				sb.append(getBigEndianHexString(ds[1]));
			}
			rtn = sb.toString();
		} 
		return rtn;
	}
	//tower
	public static class GeoPoint{
		public String id;
		public String name;
		public String lineno;
		public String line_cim_id;
		public String linename;
		public String voltage;
		public String towerserialno;
		public String isshow;		
		public String sel;
		public String towerno;
		public String is_loop;
		public String loop_cim_id;
		public String loopname;
		public double smX;
		public double smY;
		public GeoPoint(double pX,double pY){
			this.smX = pX;
			this.smY = pY;
		}
	}
	//station
	public static class GeoPoint2{
		public String id;
		public String name;
		public String subControlArea;
		public String substationType;
		public String altitude;
		public String priority;
		public String pasId;
		public String voltageLevel;
		public String voltage;
		public String flag;
		public double smX;
		public double smY;
		public GeoPoint2(double pX,double pY){
			this.smX = pX;
			this.smY = pY;
		}
	}
	
	public static class GeoLine{
		public String lineId;
		public String lineName;
		public String loopId;
		public String loopName;
		public byte[] smGeometry = null;
		/**
		 * x最小值
		 */
		public double smSdriW = 0;
		/**
		 * x最大值
		 */
		public double smSdriE = 0;
		/**
		 * y最小值
		 */
		public double smSdriS = 0;
		/**
		 * y最大值
		 */
		public double smSdriN = 0;
	}
	
	public static void main(String[] args){
	
		
		
		//000000000100000002000000
		//x:100.400779605985 
		//y:100.136303815369
		//FF26815F3F5940
		//FF26815FA6195940
		//1D55A333B9085940
		//3282417D42196940
		//1D55A333B9085940
		//1D55003F003F5940
		//1D55A333B9085940
		//x:200.789366367289 
		//y:100.136303815369
		//3282417D42196940
		//3282417D42196940
		//1D553F3F5940
		//FF26815FA6195940
		//1D55A333B9085940
		//3282417D42196940
		//1D55A333B9085940
		List<double[]> points = new ArrayList<>();
		points.add(new double[]{100.400779605985,100.136303815369});
		points.add(new double[]{200.789366367289,100.136303815369});
		
		log.info(String.valueOf(bytesToHexString(getSuperMapLineGeoLine(points).smGeometry)));
		log.info(String.valueOf((getSuperMapLineGeoLineStr(points))));
		log.info(String.valueOf(getBigEndianHexString(1)));
		log.info(String.valueOf(getBigEndianHexString(1L)));
	}
	
	
	
}
